#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
生成测试数据并填充到数据库
"""

import asyncio
import random
from datetime import datetime, timedelta

import sys
import os

# 添加项目根目录到 Python 路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from app.database.session import get_db, engine
from app.models import Base, Visitor, VerificationRecord, AuditLog, SystemConfig, User
import bcrypt
from sqlalchemy.ext.asyncio import AsyncSession

# bcrypt配置
BCRYPT_ROUNDS = 12  # 加密轮数

async def create_test_data() -> None:
    """生成测试数据"""
    # 创建数据库表
    async with engine.begin() as conn:
        await conn.run_sync(Base.metadata.drop_all)
        await conn.run_sync(Base.metadata.create_all)
    
    # 从异步生成器获取数据库会话
    async for db in get_db():
        try:
            # 创建测试用户
            await create_test_users(db)
            
            # 创建系统配置
            await create_system_configs(db)
            
            # 创建访客数据
            visitor_ids: list[int] = await create_visitors(db)
            
            # 创建核验记录
            await create_verification_records(db, visitor_ids)
            
            # 创建审计日志
            await create_audit_logs(db)
            
            print("测试数据生成成功!")
        except Exception as e:
            print(f"生成测试数据时出错: {e}")
            # get_db()已经处理了回滚
            pass

async def create_test_users(db: AsyncSession) -> None:
    """创建测试用户"""
    # 已有admin和suadmin，这里添加一些其他角色的用户
    users = [
        {
            "username": "guard1",
            "password": "Guard@123",
            "name": "张门卫",
            "email": "guard1@example.com",
            "phone": "13800138001",
            "role": "guard-守卫",
            "is_active": True
        },
        {
            "username": "guard2",
            "password": "Guard@456",
            "name": "李门卫",
            "email": "guard2@example.com",
            "phone": "13800138002",
            "role": "guard-守卫",
            "is_active": True
        },
        {
            "username": "admin2",
            "password": "Admin@789",
            "name": "王管理员",
            "email": "admin2@example.com",
            "phone": "13800138003",
            "role": "admin-管理员",
            "is_active": True
        }
    ]
    
    for user_data in users:
        # 创建用户对象
        user = User()
        user.username = str(user_data["username"])
        password_str = str(user_data["password"])
        salt = bcrypt.gensalt(rounds=BCRYPT_ROUNDS)
        password_bytes = password_str.encode('utf-8')
        hashed_bytes = bcrypt.hashpw(password_bytes, salt)
        user.password_hash = hashed_bytes.decode('utf-8')
        user.name = str(user_data["name"])
        user.email = str(user_data["email"])
        user.phone = str(user_data["phone"])
        user.role = str(user_data["role"])
        user.is_active = bool(user_data["is_active"])
        user.created_at = datetime.now()
        user.updated_at = datetime.now()
        
        db.add(user)
    
    await db.commit()
    print(f"已创建 {len(users)} 个测试用户")

async def create_system_configs(db: AsyncSession) -> None:
    """创建系统配置"""
    configs = [
        {
            "config_key": "system_name",
            "config_value": "新易访内网系统",
            "config_type": "string",
            "description": "系统名称",
            "is_encrypted": False
        },
        {
            "config_key": "qrcode_validity_period",
            "config_value": "3600",
            "config_type": "integer",
            "description": "二维码有效期（秒）",
            "is_encrypted": False
        },
        {
            "config_key": "visitor_data_retention_days",
            "config_value": "90",
            "config_type": "integer",
            "description": "访客数据保留天数",
            "is_encrypted": False
        },
        {
            "config_key": "audit_log_retention_days",
            "config_value": "180",
            "config_type": "integer",
            "description": "审计日志保留天数",
            "is_encrypted": False
        }
    ]
    
    for config_data in configs:
        config = SystemConfig()
        config.config_key = str(config_data["config_key"])
        config.config_value = str(config_data["config_value"])
        config.config_type = str(config_data["config_type"])
        config.description = str(config_data["description"])
        config.is_encrypted = bool(config_data["is_encrypted"])
        config.created_at = datetime.now()
        config.updated_at = datetime.now()
        
        db.add(config)
    
    await db.commit()
    print(f"已创建 {len(configs)} 个系统配置")

async def create_visitors(db: AsyncSession) -> list[int]:
    """创建访客数据"""
    # 随机生成访客信息
    names = ["张三", "李四", "王五", "赵六", "钱七", "孙八", "周九", "吴十"]
    companies = ["ABC科技有限公司", "XYZ贸易公司", "未来软件", "智慧建筑", "创新电子", "绿色能源"]
    visit_reasons = ["商务洽谈", "技术支持", "参观考察", "合作交流", "面试"]
    statuses = ["pending-待审核", "approved-已批准", "rejected-已拒绝", "visiting-访问中", "completed-已完成"]
    
    visitor_ids: list[int] = []
    
    # 生成50个访客记录
    for i in range(50):
        visitor = Visitor()
        visitor.name = str(random.choice(names))
        visitor.phone = str(f"13800138{i:03d}")
        visitor.id_card = str(f"11010119900101{i:04d}")
        visitor.company = str(random.choice(companies))
        visitor.visit_reason = str(random.choice(visit_reasons))
        visitor.interviewee = str(f"李{random.randint(1, 10)}工")
        visitor.planned_visit_time = datetime.now() + timedelta(days=random.randint(-7, 7))
        visitor.status = str(random.choice(statuses))
        visitor.is_special = bool(random.random() < 0.1)  # 10%概率为特殊访客
        visitor.created_at = datetime.now() + timedelta(days=random.randint(-30, 0))
        visitor.updated_at = visitor.created_at + timedelta(hours=random.randint(1, 24))
        
        # 为10个访客生成二维码
        if i < 10:
            visitor.qr_code = f"MOCK_QR_CODE_{i}"
            visitor.qr_code_expire_time = datetime.now() + timedelta(days=1)
        
        db.add(visitor)
        await db.flush()  # 获取id
        visitor_ids.append(visitor.id)
    
    await db.commit()
    print(f"已创建 {len(visitor_ids)} 个访客记录")
    return visitor_ids

async def create_verification_records(db: AsyncSession, visitor_ids: list[int]) -> None:
    """创建核验记录"""
    # 为部分访客创建核验记录
    guard_names = ["张门卫", "李门卫"]
    result_types = ["success-成功", "reject-拒绝", "pending-待审核"]  # 有效值：pending-待审核, success-成功, reject-拒绝
    guard_points = ["前门", "后门", "侧门", "一号门", "二号门"]
    guard_ids = [1, 2]  # 假设门卫ID为1和2
    visitor_names = ["张三", "李四", "王五", "赵六", "钱七"]
    
    records = 0
    
    for visitor_id in visitor_ids[:30]:  # 为前30个访客创建记录
        # 随机创建1-3条记录
        for _ in range(random.randint(1, 3)):
            record = VerificationRecord()
            record.visitor_id = int(visitor_id)
            record.visitor_name = str(random.choice(visitor_names))
            record.guard_id = int(random.choice(guard_ids))
            record.guard_name = str(random.choice(guard_names))
            record.guard_point = str(random.choice(guard_points))
            record.verify_result = str(random.choice(result_types))
            record.verify_time = datetime.now() + timedelta(days=random.randint(-7, 0), hours=random.randint(8, 18))
            record.qr_code_content = str(f"MOCK_QR_CODE_{visitor_id}")
            record.created_at = record.verify_time
            
            # 如果是拒绝，添加拒绝原因
            if record.verify_result == "reject-拒绝":
                record.rejection_reason = str("不符合访客条件")
            
            db.add(record)
            records += 1
    
    await db.commit()
    print(f"已创建 {records} 条核验记录")

async def create_audit_logs(db: AsyncSession) -> None:
    """创建审计日志"""
    operators = ["admin", "suadmin", "guard1", "guard2", "system"]
    operation_types = ["login", "logout", "create_visitor", "verify_qrcode", "update_system_config", "view_audit_log"]
    targets = ["user", "visitor", "qrcode", "system_config", "audit_log"]
    
    # 生成100条审计日志
    for i in range(100):
        log = AuditLog()
        log.operator = str(random.choice(operators))
        log.operation_type = str(random.choice(operation_types))
        log.operation_target = str(random.choice(targets))
        log.operation_details = {"action": f"test_action_{i}", "params": {}}
        log.success = bool(random.random() > 0.1)  # 90%成功率
        log.ip_address = str(f"192.168.1.{random.randint(1, 254)}")
        log.created_at = datetime.now() + timedelta(days=random.randint(-30, 0), hours=random.randint(0, 23))
        
        db.add(log)
    
    await db.commit()
    print(f"已创建 100 条审计日志")

if __name__ == "__main__":
    # 运行异步函数
    asyncio.run(create_test_data())